// 无障碍访问配置
export interface AccessibilityConfig {
  // 键盘导航
  keyboardNavigation: boolean
  // 屏幕阅读器支持
  screenReader: boolean
  // 高对比度模式
  highContrast: boolean
  // 大字体模式
  largeFont: boolean
  // 减少动画
  reducedMotion: boolean
  // 焦点指示器
  focusIndicator: boolean
  // 语音提示
  voiceAnnouncement: boolean
}

// 默认无障碍配置
export const defaultAccessibilityConfig: AccessibilityConfig = {
  keyboardNavigation: true,
  screenReader: true,
  highContrast: false,
  largeFont: false,
  reducedMotion: false,
  focusIndicator: true,
  voiceAnnouncement: false,
}

// 无障碍管理器
export class AccessibilityManager {
  private static instance: AccessibilityManager
  private config: AccessibilityConfig
  private listeners: Array<(config: AccessibilityConfig) => void> = []

  constructor() {
    this.config = { ...defaultAccessibilityConfig }
    this.initAccessibility()
  }

  static getInstance(): AccessibilityManager {
    if (!AccessibilityManager.instance) {
      AccessibilityManager.instance = new AccessibilityManager()
    }
    return AccessibilityManager.instance
  }

  // 初始化无障碍功能
  initAccessibility(): void {
    this.loadConfig()
    this.setupKeyboardNavigation()
    this.setupScreenReader()
    this.setupFocusManagement()
    this.setupMediaQueries()
    this.applyConfig()
  }

  // 加载配置
  loadConfig(): void {
    const savedConfig = localStorage.getItem('accessibility-config')
    if (savedConfig) {
      try {
        this.config = { ...defaultAccessibilityConfig, ...JSON.parse(savedConfig) }
      } catch (error) {
        console.error('加载无障碍配置失败:', error)
      }
    }

    // 检测系统偏好设置
    this.detectSystemPreferences()
  }

  // 保存配置
  saveConfig(): void {
    localStorage.setItem('accessibility-config', JSON.stringify(this.config))
    this.notifyListeners()
  }

  // 检测系统偏好设置
  detectSystemPreferences(): void {
    // 检测是否偏好减少动画
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      this.config.reducedMotion = true
    }

    // 检测是否偏好高对比度
    if (window.matchMedia('(prefers-contrast: high)').matches) {
      this.config.highContrast = true
    }

    // 检测是否偏好大字体
    if (window.matchMedia('(prefers-reduced-data: reduce)').matches) {
      this.config.largeFont = true
    }
  }

  // 设置键盘导航
  setupKeyboardNavigation(): void {
    if (!this.config.keyboardNavigation) return

    // 添加键盘事件监听
    document.addEventListener('keydown', this.handleKeyboardNavigation.bind(this))

    // 添加跳转到主内容的快捷键
    this.addSkipLinks()
  }

  // 处理键盘导航
  handleKeyboardNavigation(event: KeyboardEvent): void {
    // ESC 键关闭模态框
    if (event.key === 'Escape') {
      this.closeModals()
    }

    // Tab 键循环焦点
    if (event.key === 'Tab') {
      this.manageFocusTrap(event)
    }

    // 方向键导航
    if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
      this.handleArrowNavigation(event)
    }

    // 快捷键
    if (event.ctrlKey || event.metaKey) {
      this.handleShortcuts(event)
    }
  }

  // 添加跳转链接
  addSkipLinks(): void {
    const skipLink = document.createElement('a')
    skipLink.href = '#main-content'
    skipLink.textContent = '跳转到主内容'
    skipLink.className = 'skip-link'
    skipLink.style.cssText = `
      position: absolute;
      top: -40px;
      left: 6px;
      background: #000;
      color: #fff;
      padding: 8px;
      text-decoration: none;
      border-radius: 4px;
      z-index: 10000;
      transition: top 0.3s;
    `

    skipLink.addEventListener('focus', () => {
      skipLink.style.top = '6px'
    })

    skipLink.addEventListener('blur', () => {
      skipLink.style.top = '-40px'
    })

    document.body.insertBefore(skipLink, document.body.firstChild)
  }

  // 设置屏幕阅读器支持
  setupScreenReader(): void {
    if (!this.config.screenReader) return

    // 添加 ARIA 标签
    this.addAriaLabels()

    // 设置语义化标签
    this.setupSemanticStructure()

    // 添加实时区域
    this.setupLiveRegions()
  }

  // 添加 ARIA 标签
  addAriaLabels(): void {
    // 为没有标签的表单元素添加 aria-label
    const inputs = document.querySelectorAll('input:not([aria-label]):not([aria-labelledby])')
    inputs.forEach((input, index) => {
      if (!input.getAttribute('aria-label')) {
        input.setAttribute('aria-label', `输入框 ${index + 1}`)
      }
    })

    // 为按钮添加描述
    const buttons = document.querySelectorAll('button:not([aria-label]):not([aria-labelledby])')
    buttons.forEach((button) => {
      if (!button.textContent?.trim() && !button.getAttribute('aria-label')) {
        button.setAttribute('aria-label', '按钮')
      }
    })
  }

  // 设置语义化结构
  setupSemanticStructure(): void {
    // 确保页面有正确的标题结构
    const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
    headings.forEach((heading, index) => {
      if (!heading.id) {
        heading.id = `heading-${index + 1}`
      }
    })

    // 添加地标角色
    const main = document.querySelector('main')
    if (main && !main.getAttribute('role')) {
      main.setAttribute('role', 'main')
    }

    const nav = document.querySelector('nav')
    if (nav && !nav.getAttribute('role')) {
      nav.setAttribute('role', 'navigation')
    }
  }

  // 设置实时区域
  setupLiveRegions(): void {
    // 创建消息通知区域
    const messageRegion = document.createElement('div')
    messageRegion.id = 'message-region'
    messageRegion.setAttribute('aria-live', 'polite')
    messageRegion.setAttribute('aria-atomic', 'true')
    messageRegion.style.cssText = `
      position: absolute;
      left: -10000px;
      width: 1px;
      height: 1px;
      overflow: hidden;
    `
    document.body.appendChild(messageRegion)

    // 创建状态通知区域
    const statusRegion = document.createElement('div')
    statusRegion.id = 'status-region'
    statusRegion.setAttribute('aria-live', 'assertive')
    statusRegion.setAttribute('aria-atomic', 'true')
    statusRegion.style.cssText = messageRegion.style.cssText
    document.body.appendChild(statusRegion)
  }

  // 设置焦点管理
  setupFocusManagement(): void {
    if (!this.config.focusIndicator) return

    // 添加焦点样式
    const style = document.createElement('style')
    style.textContent = `
      .accessibility-focus-visible {
        outline: 2px solid #1890ff !important;
        outline-offset: 2px !important;
        box-shadow: 0 0 0 4px rgba(24, 144, 255, 0.2) !important;
      }
      
      .accessibility-high-contrast {
        filter: contrast(150%) !important;
      }
      
      .accessibility-large-font {
        font-size: 1.2em !important;
        line-height: 1.6 !important;
      }
      
      .accessibility-reduced-motion * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    `
    document.head.appendChild(style)

    // 监听焦点事件
    document.addEventListener('focusin', this.handleFocusIn.bind(this))
    document.addEventListener('focusout', this.handleFocusOut.bind(this))
  }

  // 处理焦点进入
  handleFocusIn(event: FocusEvent): void {
    const target = event.target as HTMLElement
    if (target && this.config.focusIndicator) {
      target.classList.add('accessibility-focus-visible')
    }
  }

  // 处理焦点离开
  handleFocusOut(event: FocusEvent): void {
    const target = event.target as HTMLElement
    if (target) {
      target.classList.remove('accessibility-focus-visible')
    }
  }

  // 设置媒体查询监听
  setupMediaQueries(): void {
    // 监听减少动画偏好
    const reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
    reducedMotionQuery.addEventListener('change', (e) => {
      this.config.reducedMotion = e.matches
      this.applyConfig()
    })

    // 监听高对比度偏好
    const highContrastQuery = window.matchMedia('(prefers-contrast: high)')
    highContrastQuery.addEventListener('change', (e) => {
      this.config.highContrast = e.matches
      this.applyConfig()
    })
  }

  // 应用配置
  applyConfig(): void {
    const body = document.body

    // 高对比度模式
    if (this.config.highContrast) {
      body.classList.add('accessibility-high-contrast')
    } else {
      body.classList.remove('accessibility-high-contrast')
    }

    // 大字体模式
    if (this.config.largeFont) {
      body.classList.add('accessibility-large-font')
    } else {
      body.classList.remove('accessibility-large-font')
    }

    // 减少动画
    if (this.config.reducedMotion) {
      body.classList.add('accessibility-reduced-motion')
    } else {
      body.classList.remove('accessibility-reduced-motion')
    }

    // 设置 CSS 变量
    document.documentElement.style.setProperty(
      '--accessibility-focus-color',
      this.config.focusIndicator ? '#1890ff' : 'transparent'
    )
  }

  // 关闭模态框
  closeModals(): void {
    // 触发关闭所有打开的模态框
    const modals = document.querySelectorAll('.ant-modal')
    modals.forEach((modal) => {
      const closeButton = modal.querySelector('.ant-modal-close')
      if (closeButton) {
        (closeButton as HTMLElement).click()
      }
    })
  }

  // 管理焦点陷阱
  manageFocusTrap(event: KeyboardEvent): void {
    const modal = document.querySelector('.ant-modal:not(.ant-modal-hidden)')
    if (!modal) return

    const focusableElements = modal.querySelectorAll(
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
    )

    if (focusableElements.length === 0) return

    const firstElement = focusableElements[0] as HTMLElement
    const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement

    if (event.shiftKey) {
      if (document.activeElement === firstElement) {
        event.preventDefault()
        lastElement.focus()
      }
    } else {
      if (document.activeElement === lastElement) {
        event.preventDefault()
        firstElement.focus()
      }
    }
  }

  // 处理方向键导航
  handleArrowNavigation(event: KeyboardEvent): void {
    const target = event.target as HTMLElement
    
    // 在菜单中使用方向键导航
    if (target.closest('.ant-menu')) {
      this.handleMenuNavigation(event)
    }
    
    // 在表格中使用方向键导航
    if (target.closest('.ant-table')) {
      this.handleTableNavigation(event)
    }
  }

  // 处理菜单导航
  handleMenuNavigation(event: KeyboardEvent): void {
    const menuItems = document.querySelectorAll('.ant-menu-item:not(.ant-menu-item-disabled)')
    const currentIndex = Array.from(menuItems).findIndex(item => 
      item.contains(document.activeElement)
    )

    if (currentIndex === -1) return

    let nextIndex = currentIndex
    if (event.key === 'ArrowDown') {
      nextIndex = (currentIndex + 1) % menuItems.length
    } else if (event.key === 'ArrowUp') {
      nextIndex = (currentIndex - 1 + menuItems.length) % menuItems.length
    }

    if (nextIndex !== currentIndex) {
      event.preventDefault()
      ;(menuItems[nextIndex] as HTMLElement).focus()
    }
  }

  // 处理表格导航
  handleTableNavigation(event: KeyboardEvent): void {
    const cell = (event.target as HTMLElement).closest('td, th')
    if (!cell) return

    const row = cell.closest('tr')
    const table = cell.closest('table')
    if (!row || !table) return

    const cellIndex = Array.from(row.children).indexOf(cell)
    const rowIndex = Array.from(table.querySelectorAll('tr')).indexOf(row)

    let targetCell: Element | null = null

    switch (event.key) {
      case 'ArrowRight':
        targetCell = row.children[cellIndex + 1]
        break
      case 'ArrowLeft':
        targetCell = row.children[cellIndex - 1]
        break
      case 'ArrowDown':
        const nextRow = table.querySelectorAll('tr')[rowIndex + 1]
        targetCell = nextRow?.children[cellIndex]
        break
      case 'ArrowUp':
        const prevRow = table.querySelectorAll('tr')[rowIndex - 1]
        targetCell = prevRow?.children[cellIndex]
        break
    }

    if (targetCell) {
      event.preventDefault()
      ;(targetCell as HTMLElement).focus()
    }
  }

  // 处理快捷键
  handleShortcuts(event: KeyboardEvent): void {
    // Ctrl+/ 显示快捷键帮助
    if (event.key === '/') {
      event.preventDefault()
      this.showShortcutHelp()
    }
  }

  // 显示快捷键帮助
  showShortcutHelp(): void {
    this.announceToScreenReader('快捷键帮助：ESC关闭弹窗，Tab切换焦点，方向键导航菜单和表格，Ctrl+/显示帮助')
  }

  // 向屏幕阅读器通知
  announceToScreenReader(message: string, priority: 'polite' | 'assertive' = 'polite'): void {
    if (!this.config.screenReader) return

    const regionId = priority === 'assertive' ? 'status-region' : 'message-region'
    const region = document.getElementById(regionId)
    
    if (region) {
      region.textContent = message
      
      // 清除消息以便下次通知
      setTimeout(() => {
        region.textContent = ''
      }, 1000)
    }
  }

  // 获取配置
  getConfig(): AccessibilityConfig {
    return { ...this.config }
  }

  // 更新配置
  updateConfig(newConfig: Partial<AccessibilityConfig>): void {
    this.config = { ...this.config, ...newConfig }
    this.applyConfig()
    this.saveConfig()
  }

  // 添加配置变化监听器
  addConfigChangeListener(listener: (config: AccessibilityConfig) => void): void {
    this.listeners.push(listener)
  }

  // 移除配置变化监听器
  removeConfigChangeListener(listener: (config: AccessibilityConfig) => void): void {
    const index = this.listeners.indexOf(listener)
    if (index > -1) {
      this.listeners.splice(index, 1)
    }
  }

  // 通知监听器
  private notifyListeners(): void {
    this.listeners.forEach(listener => listener(this.config))
  }
}

// 无障碍工具函数
export const accessibilityUtils = {
  // 设置焦点
  setFocus(element: HTMLElement, options?: FocusOptions): void {
    element.focus(options)
    
    // 滚动到可视区域
    element.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'nearest'
    })
  },

  // 生成唯一ID
  generateId(prefix = 'accessibility'): string {
    return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
  },

  // 检查元素是否可聚焦
  isFocusable(element: HTMLElement): boolean {
    const focusableSelectors = [
      'a[href]',
      'button:not([disabled])',
      'input:not([disabled])',
      'select:not([disabled])',
      'textarea:not([disabled])',
      '[tabindex]:not([tabindex="-1"])',
      '[contenteditable="true"]'
    ]

    return focusableSelectors.some(selector => element.matches(selector))
  },

  // 获取可聚焦元素
  getFocusableElements(container: HTMLElement): HTMLElement[] {
    const focusableSelectors = [
      'a[href]',
      'button:not([disabled])',
      'input:not([disabled])',
      'select:not([disabled])',
      'textarea:not([disabled])',
      '[tabindex]:not([tabindex="-1"])',
      '[contenteditable="true"]'
    ].join(', ')

    return Array.from(container.querySelectorAll(focusableSelectors))
  },

  // 创建焦点陷阱
  createFocusTrap(container: HTMLElement): () => void {
    const focusableElements = accessibilityUtils.getFocusableElements(container)
    
    if (focusableElements.length === 0) {
      return () => {}
    }

    const firstElement = focusableElements[0]
    const lastElement = focusableElements[focusableElements.length - 1]

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Tab') {
        if (event.shiftKey) {
          if (document.activeElement === firstElement) {
            event.preventDefault()
            lastElement.focus()
          }
        } else {
          if (document.activeElement === lastElement) {
            event.preventDefault()
            firstElement.focus()
          }
        }
      }
    }

    container.addEventListener('keydown', handleKeyDown)
    firstElement.focus()

    // 返回清理函数
    return () => {
      container.removeEventListener('keydown', handleKeyDown)
    }
  }
}